<script>
import { defineComponent, computed } from 'vue'
import { createNamespace, transformSize, isCssRelativeSize, getCssSizeValue, roundNumber } from '../utils'

export default defineComponent({
	name: createNamespace('AspectRatio')[0],
	options: {
		// https://uniapp.dcloud.io/matter.html#mp
		virtualHost: true
	},
	props: {
		/**
		 * 盒子宽高比
		 * 支持：比值number、a/b、a:b
		 * 宽度未知时主要是利用padding的百分比值是相对于包含块（一般是父盒子）的宽度，造出指定比例的容器
		 */
		aspectRatio: [Number, String],
		width: [Number, String],
		height: [Number, String]
	},
	emits: ['click'],
	setup(props, context) {
		// 返回数值型的比例
		const resolveAspectRatio = (ar) => {
			if (typeof ar === 'string') {
				if (ar.includes('/') || ar.includes(':')) {
					const [a, b] = ar.replace('/', ':').split(':')
					return a / b
				}
				return Number(ar)
			}
			return ar
		}
		const state = computed(() => {
			let wrapper = false
			let wrapperStyle = 'overflow:hidden;'
			let style = ''

			const { aspectRatio, width, height } = props
			const ar = resolveAspectRatio(aspectRatio)
			const w = getCssSizeValue(width)
			const wUnit = transformSize(width)
			const h = getCssSizeValue(height)
			const hUnit = transformSize(height)
			if (height) {
				if (width) {
					style += `width:${wUnit};height:${hUnit};`
				} else if (ar && !isCssRelativeSize(height)) {
					style += `width:${transformSize(h * ar)};height:${hUnit};`
				} else {
					style += `height:${hUnit};`
				}
			} else if (ar) {
				if (!width || isCssRelativeSize(width)) {
					wrapper = true
					style = `position:relative;height:0;`
					if (width) {
						// 相对尺寸的话一直相对下去就好了
						const unit = wUnit.replace(/[0-9.]/g, '')
						style += `width:${width};padding-bottom:${roundNumber(w / ar, 5)}${unit};`
					} else {
						style += `width:100%;padding-bottom:${roundNumber(100 / ar, 5)}%;`
					}
				} else {
					style += `width:${wUnit};height:${transformSize(w / ar)};`
				}
			} else if (width) {
				style += `width:${wUnit};`
			}

			if (wUnit) wrapperStyle += `width:${wUnit};`
			if (hUnit) wrapperStyle += `height:${hUnit};`

			return {
				style,
				wrapper,
				wrapperStyle: wrapperStyle,
				rootStyle: wrapperStyle + style
			}
		})

		const onClick = (e) => context.emit('click', e)

		return { state, onClick }
	}
})
</script>

<template>
	<div class="fan-aspect-ratio" :style="state.wrapperStyle">
		<template v-if="state.wrapper">
			<div :style="state.style">
				<div class="fan-aspect-ratio__box" @click="onClick">
					<slot />
				</div>
			</div>
		</template>
		<div v-else style="width: 100%; height: 100%" @click="onClick">
			<slot />
		</div>
	</div>
</template>

<style lang="less">
.fan-aspect-ratio {
	overflow: hidden;
	transition: height 0.15s linear;

	&__box {
		position: absolute !important;
		top: 0;
		bottom: 0;
		left: 0;
		right: 0;
	}
}
</style>